﻿using System;
using System.Collections.Generic;
using System.Data;
using DataAccess;
using Utility;
using System.Linq;
using Newtonsoft.Json.Linq;

namespace BusinessLogic
{
    public class JsonLogic
    {
        private JsonLogic() { }

        public static JsonLogic Instance = new JsonLogic();
        public int SelectedEffectRows
        {
            get;set;
        }
        public DataSet GetDataSet(IDictionary<string, object> formParams)
        {
            if (!formParams.ContainsKey("SP_NAME"))
            {
                return null;
            }

            string SP_NAME = formParams["SP_NAME"] as string;
          
            return GetList(SP_NAME, formParams);
        }

        public DataSet QueryDataSetAsText(IDictionary<string, object> formParams)
        {
            if (!formParams.ContainsKey("SP_NAME"))
            {
                return null;
            }

            string SP_NAME = formParams["SP_NAME"] as string;
            return QueryAsText(SP_NAME, formParams);
        }

        public DataTable QueryMergeTableAsText(IDictionary<string, object> formParams)
        {
            if (!formParams.ContainsKey("SP_NAME"))
            {
                return null;
            }
            string SP_NAME = formParams["SP_NAME"] as string;
            DataSet ds = QueryAsText(SP_NAME, formParams);

            if (ds == null) return new DataTable();
            if (ds.Tables.Count == 0) return new DataTable();
            DataTable dtblNormal = PagationCloneDataTable(ds.Tables[0], formParams);

            if (formParams.ContainsKey("MERGE_DETAIL"))
            {
                string merge_detial = formParams["MERGE_DETAIL"].ToString();
                List<Dictionary<string, object>> mergeDetailList = JSONHelper.Instance.JavaScriptDeserializationMachion<List<Dictionary<string, object>>>(merge_detial);

                StringHelper stringMergeHelper = new StringHelper();
                foreach (Dictionary<string, object> mergeDetail in mergeDetailList)
                {
                    foreach (DataRow drowNormal in dtblNormal.Rows)
                    {
                        stringMergeHelper.StringFormat8Row(drowNormal, ds, mergeDetail);
                    }
                }
            }
            dtblNormal.AcceptChanges();
            return dtblNormal;
        }

        public DataTable QueryTableAsText(IDictionary<string, object> formParams)
        {
            if (!formParams.ContainsKey("SP_NAME"))
            {
                return null;
            }

            string SP_NAME = formParams["SP_NAME"] as string;
            DataSet ds = QueryAsText(SP_NAME, formParams);
            SelectedEffectRows = 0;
            if (ds == null) return new DataTable();
            if (ds.Tables.Count == 0) return new DataTable();
            SelectedEffectRows = ds.Tables[0].Rows.Count;
            return ds.Tables[0];
            //return PagationCloneDataTable(ds.Tables[0], formParams);
        }

        public string QueryNodes(string detail_string) {
            JObject o=  JObject.Parse(detail_string);
            return "";
        }

        public DataTable GetMergeTable(IDictionary<string, object> formParams)
        {
            if (!formParams.ContainsKey("SP_NAME"))
            {
                return null;
            }
            string SP_NAME = formParams["SP_NAME"] as string;
             DataSet ds = GetList(SP_NAME, formParams);
            SelectedEffectRows = 0;
            if (ds == null) return new DataTable();
            if (ds.Tables.Count == 0) return new DataTable();
           
            DataTable dtblNormal = PagationCloneDataTable(ds.Tables[0],formParams);
            SelectedEffectRows = ds.Tables[0].Rows.Count;
            if (formParams.ContainsKey("MERGE_DETAIL"))
            {
                string merge_detial = formParams["MERGE_DETAIL"].ToString();
                List<Dictionary<string, object>> mergeDetailList = JSONHelper.Instance.JavaScriptDeserializationMachion<List<Dictionary<string, object>>>(merge_detial);

                StringHelper stringMergeHelper = new StringHelper();
                foreach (Dictionary<string, object> mergeDetail in mergeDetailList)
                {
                    foreach (DataRow drowNormal in dtblNormal.Rows)
                    {
                        stringMergeHelper.StringFormat8Row(drowNormal, ds, mergeDetail);
                    }
                }
            }
            dtblNormal.AcceptChanges();
            return dtblNormal;
        }

        public DataTable GetTable(IDictionary<string, object> formParams, bool isProfileDataTable = false, bool hasLocalQuery = true)
        {
            if (!formParams.ContainsKey("SP_NAME"))
            {
                return null;
            }

            string SP_NAME = formParams["SP_NAME"] as string;

            DataSet ds = GetList(SP_NAME, formParams);
            SelectedEffectRows = 0;

            if (ds == null) return new DataTable();
            if (ds.Tables.Count == 0) return new DataTable();
            DataTable dtbl = ds.Tables[0];
            if (dtbl.Rows.Count > 0)
            {
                if (dtbl.Columns.IndexOf("_total") > -1)
                {
                    SelectedEffectRows = Convert.ToInt32(dtbl.Rows[0]["_total"]);
                }
                else
                {
                    SelectedEffectRows = dtbl.Rows.Count;
                }
            }
            return dtbl;
        }

        public DataTable SelectRow(IDictionary<string, object> formParams, bool isProfileDataTable = false)
        {
            if (!formParams.ContainsKey("SP_NAME"))
            {
                return null;
            }
            string SP_NAME = formParams["SP_NAME"] as string;
            DataTable dtbl= OperationDA.Instance.QueryRow(SP_NAME, formParams);
            if (dtbl == null) return new DataTable();
            return dtbl;
        }

        public IDictionary<string, object> Excute(IDictionary<string, object> formParams)
        {
            string SP_NAME = string.Empty;
            string DB_NAME = string.Empty;

            try
            {
                if (!formParams.ContainsKey("SP_NAME"))
                {
                    return null;
                }

                SP_NAME = formParams["SP_NAME"] as string;

                OperationDA da = new OperationDA();
                IDictionary<string, object> outputParams = da.Operation(SP_NAME, formParams);
                Logger.Instance.WriteEventLog("DML操作", "Excute", (Dictionary<string, object>)formParams, "", LoggerType.sql);
                return outputParams;
            }
            catch (Exception ex)
            {
                Logger.Instance.WriteEventLog("DML操作", "Excute", (Dictionary<string, object>)formParams,ex,"",LoggerType.sql);
                //EmailHelper.Instance.SendMail("数据库错误", "存储过程:" + SP_NAME + "\r\n" + ex.Message);
                return null;
            }
        }


        public string GetPagationJson(DataTable dt, IDictionary<string, object> formParams)
        {
            JSONHelper _instance = JSONHelper.Instance;
            int totalRows = dt.Rows.Count;
            if (formParams.ContainsKey("_totalRows"))
            {
                totalRows = (int)formParams["_totalRows"];
            }
            return _instance.PagationDataClone2Json(DataFormatter(dt, formParams), totalRows);
        }

        public string jsonSelect(DataTable dt, IDictionary<string, object> formParams)
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject( DataFormatter(dt,formParams));
        }

        public string jsonOutput(IDictionary<string, object> outputParams)
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(outputParams);
        }

        public string jsonMenu(DataTable dt, string fatherColName, string childColName, string title)
        {
            return JSONHelper.Instance.DataTableMenuToJson(dt, fatherColName, childColName, title);
        }

        #region basic
        public DataTable GetLocalQueryTable(DataTable dtbl, IDictionary<string, object> formParams)
        {
            List<string> lstFilter =  formParams.Where(kp => kp.Key.StartsWith("LOCAL_QUERY_FORMULA_")).Select(kp =>"("+ kp.Value.ToString()+")").ToList<string>();
            string filterString = string.Join(" and ", lstFilter.ToArray());
            if (!string.IsNullOrEmpty(filterString))
            {
                dtbl.DefaultView.RowFilter = filterString;
            }

            if (formParams.ContainsKey("LOCAL_ORDERBY"))
            {
                dtbl.DefaultView.Sort = formParams["LOCAL_ORDERBY"].ToString();
            }
            else if (formParams.ContainsKey("sort") && !string.IsNullOrEmpty(formParams["sort"].ToString()))
            {
                dtbl.DefaultView.Sort = string.Format("{0} {1}", formParams["sort"], formParams.ContainsKey("order") ? "asc" : formParams["order"]);
            }
            dtbl = dtbl.DefaultView.ToTable();
            dtbl= ReformDataTable.Instance.ReformDataTableByAge(dtbl);
            return dtbl;
        }


        public DataTable PagationCloneDataTable(DataTable dt, IDictionary<string, object> formParams,bool hasLocalQuery=true)
        {
            DataTable clone = dt;
            int page = 0, row = 500;
            bool _allowPaging = false;
            if (formParams.ContainsKey("page") && formParams.ContainsKey("rows"))
            {
                page = Convert.ToInt32(formParams["page"]) - 1;
                row = Convert.ToInt32(formParams["rows"]);
                _allowPaging = true;
            }
            if (dt.Columns.IndexOf("_total") == -1  || (!_allowPaging && dt.Rows.Count>500))
            { 
                if (page > dt.Rows.Count / row || page < 0)
                {
                    page = 0;
                }
                clone = JSONHelper.Instance.PagationCloneDataTable(dt, page, row);
            }
            if (hasLocalQuery)
            {
                return GetLocalQueryTable(clone, formParams);
            }
            else
            {
                return clone;
            }
        }

        public object DataFormatter(DataTable dt, IDictionary<string, object> formParams)
        {
            const string _key = "DATATABLE_FORMATTER";
            string formatterJson = formParams.ContainsKey(_key) ? formParams[_key].ToString():"";
            return JSONHelper.Instance.DataTableFormmater(dt, formatterJson);
        }

        public DataSet QueryAsText(string procName, IDictionary<string, object> queryParams)
        {
            return OperationDA.Instance.QueryAsText(procName, queryParams);
        }


        public DataSet GetList(string procName, IDictionary<string, object> queryParams)
        {
            return OperationDA.Instance.GetList(procName, queryParams);
        }

        public IDictionary<string, object> Operation(string procName, IDictionary<string, object> queryParams)
        {
            return OperationDA.Instance.Operation(procName, queryParams);
        }

        public IDictionary<string, object> Dulpex(IDictionary<string, object> queryParams, out DataSet outputDataSet)
        {
            if (!queryParams.ContainsKey("SP_NAME"))
            {
                outputDataSet = null;
                return null;
            }
            string procName = queryParams["SP_NAME"].ToString();
            return OperationDA.Instance.ExcuteOutputDulpex(procName, queryParams, out outputDataSet);
        }

        public IDictionary<string, object> ExcuteTransation(List<IDictionary<string, object>> transParams)
        {
            return OperationDA.Instance.ExecuteTransate(transParams);
        }

        #endregion basic
    }
}